package common

import (
	"bytes"
	"cloudops/src/config"
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"k8s.io/klog/v2"
	"net/http"
	"net/url"
	"time"
)

const (
	DingAlertTitle = "logoperator钉钉告警"
	//ACCESS_TOKEN   = "c258146e7a2ba89f0596d9d8ab4c138d1226e51b7d3ac9644d413f37e9e591d8"
	//SECRET         = "SECb697bc6df4faae99b663807b67f2f0c6bd4425d74c4448fa43ba225df5eeb660"
)

// 发送钉钉消息结构体
type dingMsgNew struct {
	Msgtype string  `json:"msgtype"`
	Text    content `json:"text"`
	At      at      `json:"at"`
}

// 钉钉消息内容
type content struct {
	Content string `json:"content"`
}

// 钉钉消息at
type at struct {
	AtMobiles []string `json:"atMobiles"`
}

// 发送钉钉消息结构体
type T struct {
	At struct {
		AtMobiles []string `json:"atMobiles"`
		AtUserIds []string `json:"atUserIds"`
		IsAtAll   bool     `json:"isAtAll"`
	} `json:"at"`
	Text struct {
		Content string `json:"content"`
	} `json:"text"`
	Msgtype string `json:"msgtype"`
}

// 生成签名
func generateSign(secret string, timestamp int64) (string, error) {
	stringToSign := fmt.Sprintf("%d\n%s", timestamp, secret)
	h := hmac.New(sha256.New, []byte(secret))
	h.Write([]byte(stringToSign))
	sign := base64.StdEncoding.EncodeToString(h.Sum(nil))
	return url.QueryEscape(sign), nil
}

// 发送钉钉消息
func DingDingMsgDirectSend(imc *config.ImDingDingConf, msg string) {
	dm := dingMsgNew{Msgtype: "text"}
	dm.Text.Content = fmt.Sprintf("%s\n%s", imc.Title, msg)
	dm.At.AtMobiles = imc.AtMobiles
	bs, err := json.Marshal(&dm)
	if err != nil {
		klog.Errorf("msg:dingding.msg.json.Marshal.error dm:%v err:%v", dm, err)
		return
	}

	// 生成时间戳和签名
	timestamp := time.Now().UnixNano() / 1e6
	sign, err := generateSign(imc.Secret, timestamp)
	if err != nil {
		klog.Errorf("genearte sign error %v", err)
		return
	}

	// 更新请求URL
	url := fmt.Sprintf("https://oapi.dingtalk.com/robot/send?access_token=%s&timestamp=%d&sign=%s", imc.Access_Token, timestamp, sign)
	fmt.Println(url)
	res, err := http.Post(url, "application/json", bytes.NewBuffer(bs))
	if err != nil {
		klog.Errorf("send.dingding.error err:%v msg:%v", err, msg)
		return
	}
	defer res.Body.Close()

	if res.StatusCode != http.StatusOK {
		klog.Errorf("send.dingding.status_code.error code:%v msg:%v", res.StatusCode, msg)
		return
	}

	if res.StatusCode != 200 {
		klog.Errorf("send.dingding.error code:%v msg:%v", res.StatusCode, dm)
		return
	}

	// 调试代码
	//body, _ := io.ReadAll(res.Body)
	//klog.Infof("send.dingding.success msg:%v body:%v", res.StatusCode, string(body), dm.Text.Content)
	klog.Infof("send.dingding.success msg:%v body:%v", res.StatusCode, dm.Text.Content)
}

func ImTestSent(sc *config.ServerConfig) {
	imc := config.ImDingDingConf{
		BotApiAddr:   sc.ImDingDingC.BotApiAddr, // 只需保留基本 URL
		Title:        "通知ntp模块处理结果",
		AtMobiles:    []string{""}, // 填入需要 @ 的手机号
		Access_Token: sc.ImDingDingC.Access_Token,
		Secret:       sc.ImDingDingC.Secret,
	}
	msg := "测试钉钉消息发送"
	DingDingMsgDirectSend(&imc, msg)
}
